package com.xjh.utils.util;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson2.JSON;
import com.xjh.utils.datautils.WinxinApprovalNode;
import org.apache.commons.lang3.StringUtils;
import org.dom4j.*;


import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author XuJianHua
 * @date 2022-08-29 13:48:02
 * @description 纯用dom4j依赖
 */
public class XmlUtil2 {

    /**
     * xml转json
     *
     * @param xmlStr
     * @return
     * @throws DocumentException
     */
    public static JSONObject xml2Json(String xmlStr) {
        Document doc = null;
        try {
            doc = DocumentHelper.parseText(xmlStr);
        } catch (DocumentException e) {
            e.printStackTrace();
        }
        JSONObject json = new JSONObject();
        dom4j2Json(doc.getRootElement(), json);
        return json;
    }

    /**
     * xml转json
     *
     * @param element
     * @param json
     */
    private static void dom4j2Json(Element element, JSONObject json) {
        // 如果是属性
        for (Object o : element.attributes()) {
            Attribute attr = (Attribute) o;
            if (StringUtils.isNotBlank(attr.getValue())) {
                json.put("@" + attr.getName(), attr.getValue());
            }
        }
        List<Element> chdEl = element.elements();
        if (chdEl.isEmpty() && StringUtils.isNotBlank(element.getText())) {// 如果没有子元素,只有一个值
            json.put(element.getName(), element.getText());
        }
        for (Element e : chdEl) {// 有子元素
            if (!e.elements().isEmpty()) {// 子元素也有子元素
                JSONObject chdjson = new JSONObject();
                dom4j2Json(e, chdjson);
                Object o = json.get(e.getName());
                if (o != null) {
                    JSONArray jsona = null;
                    if (o instanceof JSONObject) {// 如果此元素已存在,则转为jsonArray
                        JSONObject jsono = (JSONObject) o;
                        json.remove(e.getName());
                        jsona = new JSONArray();
                        jsona.add(jsono);
                        jsona.add(chdjson);
                    }
                    if (o instanceof JSONArray) {
                        jsona = (JSONArray) o;
                        jsona.add(chdjson);
                    }
                    json.put(e.getName(), jsona);
                } else {
                    if (!chdjson.isEmpty()) {
                        json.put(e.getName(), chdjson);
                    }
                }
            } else {// 子元素没有子元素
                for (Object o : element.attributes()) {
                    Attribute attr = (Attribute) o;
                    if (StringUtils.isNotBlank(attr.getValue())) {
                        json.put("@" + attr.getName(), attr.getValue());
                    }
                }
                if (!e.getText().isEmpty()) {
                    json.put(e.getName(), e.getText());
                }
            }
        }
    }

    public static void main(String[] args) throws IOException {
        String xmlData = "<xml><ToUserName><![CDATA[wx7e4271dc09a7a1fd]]></ToUserName><FromUserName><![CDATA[sys]]></FromUserName><CreateTime>1661742844</CreateTime><MsgType><![CDATA[event]]></MsgType><Event><![CDATA[sys_approval_change]]></Event><AgentID>3010040</AgentID><ApprovalInfo><SpNo>202208290005</SpNo><SpName><![CDATA[付款申请]]></SpName><SpStatus>4</SpStatus><TemplateId><![CDATA[1970325006023083_1688851476324306_583259002_1524556136]]></TemplateId><ApplyTime>1661742687</ApplyTime><Applyer><UserId><![CDATA[57818]]></UserId><Party><![CDATA[744]]></Party><Vid>1688856583394573</Vid></Applyer><SpRecord><SpStatus>2</SpStatus><ApproverAttr>1</ApproverAttr><Details><Approver><UserId><![CDATA[85655]]></UserId><Vid>1688856634368152</Vid></Approver><Speech><![CDATA[]]></Speech><SpStatus>2</SpStatus><SpTime>1661742696</SpTime></Details></SpRecord><SpRecord><SpStatus>2</SpStatus><ApproverAttr>1</ApproverAttr><Details><Approver><UserId><![CDATA[99040]]></UserId><Vid>1688851626748101</Vid></Approver><Speech><![CDATA[]]></Speech><SpStatus>2</SpStatus><SpTime>1661742728</SpTime></Details></SpRecord><SpRecord><SpStatus>1</SpStatus><ApproverAttr>1</ApproverAttr><Details><Approver><UserId><![CDATA[78226]]></UserId><Vid>1688851952904945</Vid></Approver><Speech><![CDATA[]]></Speech><SpStatus>1</SpStatus><SpTime>0</SpTime></Details></SpRecord><SpRecord><SpStatus>1</SpStatus><ApproverAttr>1</ApproverAttr><Details><Approver><UserId><![CDATA[31049]]></UserId><Vid>1688851476323811</Vid></Approver><Speech><![CDATA[]]></Speech><SpStatus>1</SpStatus><SpTime>0</SpTime></Details></SpRecord><SpRecord><SpStatus>1</SpStatus><ApproverAttr>1</ApproverAttr><Details><Approver><UserId><![CDATA[20784]]></UserId><Vid>1688851476323695</Vid></Approver><Speech><![CDATA[]]></Speech><SpStatus>1</SpStatus><SpTime>0</SpTime></Details></SpRecord><Notifyer><UserId><![CDATA[96332]]></UserId><Vid>1688849972470818</Vid></Notifyer><Notifyer><UserId><![CDATA[22679]]></UserId><Vid>1688851476323724</Vid></Notifyer><Notifyer><UserId><![CDATA[78226]]></UserId><Vid>1688851952904945</Vid></Notifyer><Notifyer><UserId><![CDATA[42614]]></UserId><Vid>1688855519330981</Vid></Notifyer><StatuChangeEvent>6</StatuChangeEvent></ApprovalInfo></xml>\n";

        JSONObject jsonObject = xml2Json(xmlData);
        Map<String, Object> notifyMap = JSON.parseObject(jsonObject.toJSONString(), Map.class);
        System.out.println(jsonObject);
        System.out.println(notifyMap.get("ApprovalInfo"));
        // 获取审批信息
        Map<String, Object> approvalInfoMap = JSON.parseObject(JSON.toJSONString(notifyMap.get("ApprovalInfo")), Map.class);
        // 获取审批编号
        String spNo = approvalInfoMap.get("SpNo").toString();
        /*
        SpRecord(list)
            --SpStatus
            --ApproverAttr
            --Details(map)
                --Speech
                --SpStatus
                --SpTime(1661742696)
                --Approver
                    --UserId
                    --Vid
        * * * */
        List<Map<String, Object>> SpRecordList = JSON.parseObject(JSON.toJSONString(approvalInfoMap.get("SpRecord")), List.class);
        List<WinxinApprovalNode> winxinApprovalNodeList = new ArrayList<>();
        AtomicInteger i = new AtomicInteger(1);
        SpRecordList.forEach(e -> {
            WinxinApprovalNode winxinApprovalNode = new WinxinApprovalNode();
            winxinApprovalNode.setSpNo(Long.parseLong(spNo));
            Map<String, Object> spRecord = JSON.parseObject(JSON.toJSONString(e), Map.class);
            winxinApprovalNode.setSpStatus(Integer.parseInt(spRecord.get("SpStatus").toString()));
            Map<String, Object> details = JSON.parseObject(JSON.toJSONString(spRecord.get("Details")), Map.class);
            // 审批时间戳转成date
            if(!details.get("SpTime").equals("0")){
                String spTime = DateUtils.timeStamp2Date(details.get("SpTime").toString(), "yyyy-MM-dd");
                winxinApprovalNode.setSpTime(spTime);
            }
            // 获取审批人id
            Map<String, String> Approver = JSON.parseObject(JSON.toJSONString(details.get("Approver")), Map.class);
            winxinApprovalNode.setApprovalId(Integer.parseInt(Approver.get("UserId")));
            winxinApprovalNode.setNodeSort(i.getAndIncrement());
            winxinApprovalNodeList.add(winxinApprovalNode);
        });
        System.out.println(winxinApprovalNodeList);
        System.out.println(JSON.toJSONString(winxinApprovalNodeList));

        // 将审批节点信息保存到数据库（如何排序、当第二次回调时，如何判断该回调节点是否已保存，如何去更新当前节点的状态，根据spno查出所有节点，找出状态改变的，并修改，所有审批做一张表就可以了）
        // 需要字段 审批编号/审批状态/审批人/排序字段/如果已审批，填写审批时间/
        // todo 查询数据库是否有该审批提交记录
        // 没有，则根据审批编号获取审批详情,根据返回信息新增审批记录
        // 有，则更新审批状态


    }

}
